home *** CD-ROM | disk | FTP | other *** search
-
- Small doc on using SVGA with DOS32.
-
- 1. Check if the videomode we want is supported on the computer.
- The problem here is that we need some low memory, where we can let the VBE
- put some info about the mode. This is solved, however, by using the 8k
- buffer that DOS32 uses for file I/O.
- (We'll make a near ptr to the videomemory when we're at function 0ee02h
- anyway.)
-
- --->8----- API.DOC ----------
- GET DOS32 ADDRESS INFORMATION V3.01+
-
- IN: AX = EE02h
-
- OUT: EBX = 32bit linear address of the program segment
- EDX = Total size in bytes of the programs .EXE file after
- linking.
- ESI = Offset address of PSP ( Program Segment Prefix )
- EDI = Offset address of Program Environment
- ECX = Offset address of the programs .EXE file name and
- path (in ASCIZ format, i.e. terminates with a zero)
- AX = Real mode segment value of the 8Kb buffer that is
- used by the file read/write services.
- ---8<----- API.DOC ----------
-
- The values we need here are AX and EBX, we need to make a near pointer out
- of that realmode segment value.
-
- lowmemptr dd ?
- lowmemseg dw ?
- linearadr dd ?
- videomem dd ?
-
- mov eax,0ee02h
- int 31h
- mov lowmemseg,ax
- mov linearadr,ebx
- push ax ;\
- xor eax,eax ; > Clears the high bits of eax
- pop ax ;/
- shl eax,4 ; Makes eax the absolute address of the RM segment
- sub eax,ebx ; Makes eax a near pointer to the RM segment
- mov lowmemptr,eax
- mov eax,0a0000h
- sub eax,ebx
- mov videomem,eax
-
- Now when we have our segment, and accompanying near pointer, we can make a
- real mode callback to the VBE.
-
- --->8----- API.DOC ----------
- ...expects a pointer to a real
- mode call structure whish is used to passing all registers to and
- from the real mode switch. The format of the structure is defined
- as: Offset Register
- 00h EDI
- 04h ESI
- 08h EBP
- 0Ch Reserved by system
- 10h EBX
- 14h EDX
- 18h ECX
- 1Ch EAX
- 20h Flags
- 22h ES
- 24h DS
- 26h FS
- 28h GS
- 2Ah IP
- 2Ch CS
- 2Eh SP
- 30h SS
-
- Simulate a Real Mode interrupt V3.00+
-
- IN:
- AX = 0300h
- BL = Interrupt number
- BH = Flags
- Bit 0 = 1 resets the interrupt controller and A20
- line. Other flags reserved and must be 0
- CX = Number of words to copy from protected mode to
- real mode stack
- ES:EDI = Selector:Offset of real mode call structure
-
- OUT:
- If function was successful:
- Carry flag is clear.
- ES:(E)DI = Selector:Offset of modified real mode call
- structure
-
- If function was not successful:
- Carry flag is set.
- ---8<----- API.DOC ----------
-
- So, we need a structure defined as described in API.DOC:
-
- --->8----- GFX.ASM ----------
- _ label
- _edi label dword
- _di label word
- _dih db ?
- _dil db ?
- _edih db ?
- _edil db ?
- _esi label dword
- _si label word
- _sih db ?
- _sil db ?
- _esih db ?
- _esil db ?
- _ebp label dword
- _bp label word
- _bph db ?
- _bpl db ?
- _ebph db ?
- _ebpl db ?
- _reserv dd ?
- _ebx label dword
- _bx label word
- _bh db ?
- _bl db ?
- _ebh db ?
- _ebl db ?
- _edx label dword
- _dx label word
- _dh db ?
- _dl db ?
- _edh db ?
- _edl db ?
- _ecx label dword
- _cx label word
- _ch db ?
- _cl db ?
- _ech db ?
- _ecl db ?
- _eax label dword
- _ax label word
- _ah db ?
- _al db ?
- _eah db ?
- _eal db ?
- _flags dw ?
- _es dw ?
- _ds dw ?
- _fs dw ?
- _gs dw ?
- _ip dw ?
- _cs dw ?
- _sp dw ?
- _ss dw 0
- ---8<----- GFX.ASM ----------
-
- --->8----- INTERRUP.LST ----------
- --------V-104F00-----------------------------
- INT 10 - VESA SuperVGA BIOS (VBE) - GET SuperVGA INFORMATION
- AX = 4F00h
- ES:DI -> buffer for SuperVGA information (see #0063)
- Return: AL = 4Fh if function supported
- AH = status
- 00h successful
- ES:DI buffer filled
- 01h failed
- ---VBE v2.0---
- 02h function not supported by current hardware configuration
- 03h function invalid in current video mode
- Desc: determine whether VESA BIOS extensions are present and the capabilities
- supported by the display adapter
- SeeAlso: AX=4E00h,AX=4F01h,AX=7F00h,AX=A00Ch
- Index: installation check;VESA SuperVGA
-
- Format of SuperVGA information:
- Offset Size Description (Table 0063)
- 00h 4 BYTEs (ret) signature ("VESA")
- (call) VESA 2.0 request signature ("VBE2"), required to receive
- version 2.0 info
- 04h WORD VESA version number (one-digit minor version)
- 06h DWORD pointer to OEM name
- "761295520" for ATI
- 0Ah DWORD capabilities flags (see #0064)
- 0Eh DWORD pointer to list of supported VESA and OEM video modes
- (list of words terminated with FFFFh)
- 12h WORD total amount of video memory in 64K blocks
- ---VBE v1.x ---
- 14h 236 BYTEs reserved
- ---VBE v2.0 ---
- 14h WORD OEM software version
- 16h DWORD pointer to vendor name
- 1Ah DWORD pointer to product name
- 1Eh DWORD pointer to product revision string
- 22h 222 BYTEs reserved
- 100h 256 BYTEs OEM scratchpad
- Notes: the list of supported video modes is stored in the reserved portion of
- the SuperVGA information record by some implementations, and it may
- thus be necessary to either copy the mode list or use a different
- buffer for all subsequent VESA calls
- the 1.1 VESA document specifies 242 reserved bytes at the end, so the
- buffer should be 262 bytes to ensure that it is not overrun; for
- v2.0, the buffer should be 512 bytes
- the S3 specific video modes will most likely follow the FFFFh
- terminator at the end of the standard modes. A search must then
- be made to find them, FFFFh will also terminate this second list
-
- Bitfields for VESA capabilities:
- Bit(s) Description (Table 0064)
- 0 DAC can be switched into 8-bit mode
- 1 non-VGA controller
- 2 programmed DAC with blank bit
- 3-31 reserved
- ---8<----- INTERRUP.LST ----------
-
- Now, we need to set up the values to do the callback:
-
- mov ax,lowmemseg
- mov _es,ax
- mov _di,0
- mov _ax,4f00h
- mov eax,300h
- mov ebx,10h
- xor ecx,ecx
- lea edi,_ ;our RM callback structure
- int 31h
-
- If all went well, (ah=00h, al=4fh), we should now have a realmode seg:ofs ptr
- to a word list of supported video modes. Make it a near ptr and scan it to
- see if what we want is available:
-
- cmp _ax,4fh
- jne vbe_error
- xor eax,eax
- xor ebx,ebx
- mov ax,word ptr lowmemptr[0eh]
- mov bx,word ptr lowmemptr[10h]
- shl ebx,4
- add eax,ebx
- sub eax,linearadr
- mov esi,eax
- mov bx,101h ;desired video mode
- loop1:
- lodsw
- cmp ax,-1
- je mode_not_supported
- cmp ax,bx
- jne loop1
-
- We've got our video mode! :)
-
- 2. We need the window granularity of this mode to do proper bankswitching.
- This means interfacing the VBE, and using the RM buffer again.
-
- --->8----- INTERRUP.LST ----------
- --------V-104F01-----------------------------
- INT 10 - VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION
- AX = 4F01h
- CX = SuperVGA video mode
- ES:DI -> 256-byte buffer for mode information (see #0065)
- Return: AL = 4Fh if function supported
- AH = status
- 00h successful
- ES:DI buffer filled
- 01h failed
- Desc: determine the attributes of the specified video mode
- SeeAlso: AX=4F00h,AX=4F02h
-
- Format of VESA SuperVGA mode information:
- Offset Size Description (Table 0065)
- 00h WORD mode attributes (see #0066)
- 02h BYTE window attributes, window A (see #0067)
- 03h BYTE window attributes, window B (see #0067)
- 04h WORD window granularity in KB
- 06h WORD window size in KB
- 08h WORD start segment of window A
- 0Ah WORD start segment of window B
- 0Ch DWORD -> FAR window positioning function (equivalent to AX=4F05h)
- 10h WORD bytes per scan line
- ---remainder is optional for VESA modes in v1.0/1.1, needed for OEM modes---
- 12h WORD width in pixels (graphics) or characters (text)
- 14h WORD height in pixels (graphics) or characters (text)
- 16h BYTE width of character cell in pixels
- 17h BYTE height of character cell in pixels
- 18h BYTE number of memory planes
- 19h BYTE number of bits per pixel
- 1Ah BYTE number of banks
- 1Bh BYTE memory model type (see #0068)
- 1Ch BYTE size of bank in KB
- 1Dh BYTE number of image pages
- 1Eh BYTE reserved (0)
- ---VBE v1.2+---
- 1Fh BYTE red mask size
- 20h BYTE red field position
- 21h BYTE green mask size
- 22h BYTE green field size
- 23h BYTE blue mask size
- 24h BYTE blue field size
- 25h BYTE reserved mask size
- 26h BYTE reserved mask position
- 27h BYTE direct color mode info
- bit 0: color ramp is programmable
- bit 1: bytes in reserved field may be used by application
- ---VBE v2.0 ---
- 28h DWORD physical address of linear video buffer
- 2Ch DWORD pointer to start of offscreen memory
- 30h WORD KB of offscreen memory
- 32h 206 BYTEs reserved (0)
-
- Bitfields for VESA SuperVGA mode attributes:
- Bit(s) Description (Table 0066)
- 0 mode supported
- 1 optional information available
- 2 BIOS output supported
- 3 set if color, clear if monochrome
- 4 set if graphics mode, clear if text mode
- ---VBE v2.0 ---
- 5 mode is not VGA-compatible
- 6 bank-switched mode not supported
- 7 linear framebuffer mode supported
-
- Bitfields for VESA SuperVGA window attributes:
- Bit(s) Description (Table 0067)
- 0 exists
- 1 readable
- 2 writable
- 3-7 reserved
-
- (Table 0068)
- Values for VESA SuperVGA memory model type:
- 00h text
- 01h CGA graphics
- 02h HGC graphics
- 03h 16-color (EGA) graphics
- 04h packed pixel graphics
- 05h "sequ 256" (non-chain 4) graphics
- 06h direct color (HiColor, 24-bit color)
- 07h YUV (luminance-chrominance, also called YIQ)
- 08h-0Fh reserved for VESA
- 10h-FFh OEM memory models
- ---8<----- INTERRUP.LST ----------
-
- mov ax,lowmemseg
- mov _es,ax
- mov _di,0
- mov _ax,4f01h
- mov _cx,101h ;video mode
- mov eax,300h
- mov ebx,10h
- xor ecx,ecx
- lea edi,_ ;our RM callback structure
- int 31h
-
- If all is OK, we will have the wgran parameter at offset 4 in the RM
- segment. However, it is specified in KB, so we need to shl with 10 to get
- byte size.
-
- wgran dd ?
-
- cmp _ax,4fh
- jne vbe_error
- xor ebx,ebx
- mov bx,word ptr lowmemptr[4]
- shl ebx,10
- mov wgran,ebx
-
- We've got granularity. :)
-
- 3. Allocate memory for our virtual screen and switch to the SVGA mode.
- This is really simple to do.
-
- --->8----- API.DOC ----------
- ALLOCATE A MEMORY BLOCK V3.00+
-
- The entire application code,data and stack is initially
- contained in one large memory block. This service here is used for
- allocating extra memory blocks for the application.
-
- IN: AX = EE42h
- EDX = Size of the memory block requested to allocate in
- bytes.
-
- OUT: EAX = The actual allocated size of the memory block in bytes
- EDX = Near pointer to the base address of the block relative
- to the main program segment.
-
- If the returned size was less than the requested size then
- the Carry flag is set otherwise the carry flag is cleared.
-
- Notes:
- o The value expected in EDX will be rounded off to the next
- 4KB boundary. Example, allocating 51001h bytes will actually
- allocate 52000h bytes.
- o Never call this function in a interrupt handler or after
- using the terminated and stay resident function ( AX=EE30h ).
- o If EAX is returned with zero then no memory was allocated and
- contents of EDX are undefined.
- o The function will fail if the requested size is zero.
- o No more than 64 allocations can be made. If the application
- requires a faster more versatile memory management then
- please use Peter Anderson's memory sub-functions from PAL
- library. See example files on how to use. This function here
- is should used a minimum number of times.
- o When not running under a DPMI server ( i.e Raw,XMS or VCPI )
- then extended memory is allocated before conventional memory
- is. For example, if there is no more extended memory free
- then conventional memory will be allocated. In either case
- DOS32 sets up the 386 page tables such that the allocated
- memory is addressed in a straight linear block when it may
- actually be physically scattered throughout RAM.
- ---8<----- API.DOC ----------
-
- vscreen dd ?
-
- mov eax,0ee42h
- mov edx,640*480
- int 31h
- jc not_enough_memory
- mov vscreen,edx
-
- mov eax,4f02h
- mov ebx,101h ;our video mode..
- int 10h
-
- Done. :)
-
- 4. Put something on the virtual screen.
- 5. Flip the virtual screen out to video memory.
- This is not the best way to do it, but it's fairly simple to understand.
-
- flip proc
- push eax ebx ecx edx esi edi ebp
- xor dx,dx ;bank counter
- xor ebx,ebx ;used to clear the buffer
- mov ebp,640*480 ;bytes left to move-counter
- mov esi,vscreen
- mov edi,videomem
-
- outer_loop:
- call setbank
- cmp ebp,65536
- jae mov64k
- mov ecx,ebp
- sub ebp,ecx ;update counter
- shr ecx,2 ;divide by 4 to get number of dwords to move
- jmp loop_start
- mov64k: sub ebp,65536
- mov ecx,16384
- loop_start:
- mov eax,[esi] ;read a dword from the buffer
- mov [edi],eax ;and write it to video mem
- mov [esi],ebx ;clear the dword in the buffer
- add esi,4 ;update pointers
- add edi,4 ;update pointers
- dec ecx
- jnz loop_start ;loop for 16384 times, this will move 65536 bytes..
- inc edx ;increase bank counter
- sub edi,65536
- cmp ebp,3 ;check if we have more than 3 bytes left,
- ja outer_loop ;if so then jump up
- or ebp,ebp ;are we completely done?
- jz flpbye ;yes, then quit..
-
- mov ecx,ebp ;otherwise, move these bytes to video mem
- loop2_start: ;this loop is used to move the bytes left
- mov al,[esi] ;read one byte from buffer
- mov [edi],al ;and write to video mem
- mov [esi],bl ;clear buffer
- inc esi ;increase source pointer
- inc edi ;increase destination pointer
- dec ecx
- jnz loop2_start ;play it again, Sam!
- flpbye: pop ebp edi esi edx ecx ebx eax
- retn
- flip endp
-
- setbank proc
- push ax bx dx
- mov ax,4f05h
- xor bx,bx
- int 10h
- pop dx bx ax
- retn
- setbank endp
-
- OK! That's all folks. Check out DOS32VBE.ASM included in the
- package, I've put together the different sources listed in this
- document, and made a simple filling-routine. Enjoy, and feel free
- to send comments to stuge@kuai.se! :)
- -- Peter Stuge aka CareBear\ of ComeDY
-